﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Components
{
    /// <summary>
    /// 
    /// </summary>
    public class SimpleDataTypeUtil
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="simpleDataType"></param>
        /// <returns></returns>
        public static object GetNullValue(SimpleDataType simpleDataType)
        {
            switch (simpleDataType)
            {
                case SimpleDataType.IntNumberType:
                    //int? intval=null;
                    //return intval;
                    return int.MinValue;
                case SimpleDataType.DecimalNumberType:
                    return decimal.MinValue;
                case SimpleDataType.TextType:
                    return string.Empty;
                case SimpleDataType.YesNoType:
                    return false;
                case SimpleDataType.DateTimeType:
                    return TimeUtil.DbMinTime;
                case SimpleDataType.GuidType:
                    return Guid.Empty;
                case SimpleDataType.DoubleNumberType:
                    return double.NegativeInfinity;
                case SimpleDataType.EnumType:
                    return -1;
                default:
                    return null;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static int[] GetAllSimpleDataTypes()
        {
            return new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataType"></param>
        /// <param name="fieldValue"></param>
        /// <returns></returns>
        public static bool IsNullValue(SimpleDataType dataType, string fieldValue)
        {
            bool isNull = true;
            if (!string.IsNullOrEmpty(fieldValue))
            {
                switch (dataType)
                {
                    case SimpleDataType.IntNumberType:
                        try
                        {
                            double dblVal = double.Parse(fieldValue);
                            int intVal = (int)dblVal;
                            if (intVal != (int)SimpleDataTypeUtil.GetNullValue(dataType))
                            {
                                isNull = false;
                            }
                        }
                        catch
                        { }
                        break;
                    case SimpleDataType.DecimalNumberType:
                        try
                        {
                            decimal decimalVal = decimal.Parse(fieldValue);
                            if (decimalVal > decimal.MinValue)
                                isNull = false;
                        }
                        catch
                        { }
                        break;
                    case SimpleDataType.TextType:
                        try
                        {
                            string strVal = fieldValue;
                            if (strVal != (string)SimpleDataTypeUtil.GetNullValue(dataType))
                            {
                                isNull = false;
                            }
                        }
                        catch
                        { }
                        break;
                    case SimpleDataType.YesNoType:
                        try
                        {
                            bool.Parse(fieldValue);
                            isNull = false;
                        }
                        catch
                        { }
                        break;
                    case SimpleDataType.DateTimeType:
                        try
                        {
                            DateTime dtVal = DateTime.Parse(fieldValue);
                            if (dtVal != (DateTime)SimpleDataTypeUtil.GetNullValue(dataType))
                            {
                                isNull = false;
                            }
                        }
                        catch
                        { }
                        break;
                    case SimpleDataType.GuidType:
                        try
                        {
                            Guid guid = new Guid(fieldValue);
                            if (guid == Guid.Empty)
                            {
                                isNull = true;
                            }
                            else
                                isNull = false;
                        }
                        catch
                        {
                        }
                        break;
                    case SimpleDataType.DoubleNumberType:
                        try
                        {
                            double dblValue = double.Parse(fieldValue);
                            if (dblValue > double.NegativeInfinity && dblValue < double.PositiveInfinity)
                                isNull = false;
                        }
                        catch
                        { }
                        break;
                    case SimpleDataType.EnumType:
                        try
                        {
                            int enumVal = int.Parse(fieldValue);
                            if (enumVal >= 0)
                                isNull = false;
                        }
                        catch
                        { }
                        break;
                    default:
                        break;
                }
            }
            return isNull;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataType"></param>
        /// <param name="fieldValue"></param>
        /// <returns></returns>
        public static bool IsNullValue(SimpleDataType dataType, object fieldValue)
        {
            if (fieldValue == null)
                return true;
            else if (dataType == SimpleDataType.EnumType)
            {
                int enumVal = (int)fieldValue;
                if (enumVal >= 0)
                    return false;
                else
                    return true;
            }
            else
            {
                return SimpleDataTypeUtil.IsNullValue(dataType, fieldValue.ToString());
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataType"></param>
        /// <param name="fieldValue"></param>
        /// <returns></returns>
        public static object ReadDbValue(SimpleDataType dataType, object fieldValue)
        {
            if (SimpleDataTypeUtil.IsNullValue(dataType, fieldValue))
                return null;
            else
            {
                object value = null;
                switch (dataType)
                {
                    case SimpleDataType.IntNumberType:
                        value = int.Parse(fieldValue.ToString());
                        break;
                    case SimpleDataType.DecimalNumberType:
                        value = decimal.Parse(fieldValue.ToString());
                        break;
                    case SimpleDataType.TextType:
                        value = fieldValue.ToString();
                        break;
                    case SimpleDataType.YesNoType:
                        value = bool.Parse(fieldValue.ToString());
                        break;
                    case SimpleDataType.DateTimeType:
                        value = DateTime.Parse(fieldValue.ToString());
                        break;
                    case SimpleDataType.GuidType:
                        value = new Guid(fieldValue.ToString());
                        break;
                    case SimpleDataType.IntListType:
                        value = fieldValue as List<int>;
                        break;
                    case SimpleDataType.StringListType:
                        value = fieldValue as List<string>;
                        break;
                    case SimpleDataType.DoubleNumberType:
                        value = (double)fieldValue;
                        break;
                    case SimpleDataType.EnumType:
                        value = (int)fieldValue;
                        break;
                    default:
                        break;
                }
                return value;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fieldValue"></param>
        /// <returns></returns>
        public static string ReadString(object fieldValue)
        {
            object value = SimpleDataTypeUtil.ReadDbValue(SimpleDataType.TextType, fieldValue);
            if (value == null || value == SimpleDataTypeUtil.GetNullValue(SimpleDataType.TextType))
                return null;
            else
                return value.ToString();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fieldValue"></param>
        /// <returns></returns>
        public static int ReadInt(object fieldValue)
        {
            object value = SimpleDataTypeUtil.ReadDbValue(SimpleDataType.IntNumberType, fieldValue);
            if (value == null || value == SimpleDataTypeUtil.GetNullValue(SimpleDataType.IntNumberType))
                return (int)SimpleDataTypeUtil.GetNullValue(SimpleDataType.IntNumberType);
            else
                return int.Parse(value.ToString());
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fieldValue"></param>
        /// <returns></returns>
        public static decimal ReadDecimalNumber(object fieldValue)
        {
            object value = SimpleDataTypeUtil.ReadDbValue(SimpleDataType.DecimalNumberType, fieldValue);
            if (value == null || value == SimpleDataTypeUtil.GetNullValue(SimpleDataType.DecimalNumberType))
                return (decimal)SimpleDataTypeUtil.GetNullValue(SimpleDataType.DecimalNumberType);
            else
                return decimal.Parse(value.ToString());
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fieldValue"></param>
        /// <returns></returns>
        public static bool ReadBoolean(object fieldValue)
        {
            object value = SimpleDataTypeUtil.ReadDbValue(SimpleDataType.YesNoType, fieldValue);
            if (value == null)
                return (bool)SimpleDataTypeUtil.GetNullValue(SimpleDataType.YesNoType);
            else
                return bool.Parse(value.ToString());
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fieldValue"></param>
        /// <returns></returns>
        public static DateTime ReadDateTime(object fieldValue)
        {
            object value = SimpleDataTypeUtil.ReadDbValue(SimpleDataType.DateTimeType, fieldValue);
            if (value == null || value == SimpleDataTypeUtil.GetNullValue(SimpleDataType.DateTimeType))
                return (DateTime)SimpleDataTypeUtil.GetNullValue(SimpleDataType.DateTimeType);
            else
                return DateTime.Parse(value.ToString());
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataType"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static object ToDbValue(SimpleDataType dataType, object value)
        {
            if (SimpleDataTypeUtil.IsNullValue(dataType, value))
                return DBNull.Value;
            else
            {
                switch (dataType)
                {
                    case SimpleDataType.DateTimeType:
                        return (DateTime)value;
                    case SimpleDataType.DecimalNumberType:
                        return (decimal)value;
                    case SimpleDataType.IntNumberType:
                        return (int)value;
                    case SimpleDataType.TextType:
                        return value;
                    case SimpleDataType.YesNoType:
                        return (bool)value;
                    case SimpleDataType.GuidType:
                        return new Guid(value.ToString());
                    case SimpleDataType.IntListType:
                        return (List<int>)value;
                    case SimpleDataType.StringListType:
                        return (List<string>)value;
                    case SimpleDataType.DoubleNumberType:
                        return (double)value;
                    case SimpleDataType.EnumType:
                        return (int)value;
                    default:
                        return value;
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataType"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static object ToDbValue(SimpleDataType dataType, string value)
        {
            if (SimpleDataTypeUtil.IsNullValue(dataType, value))
                return DBNull.Value;
            else
            {
                switch (dataType)
                {
                    case SimpleDataType.DateTimeType:
                        DateTime dtVal;
                        DateTime.TryParse(value, out dtVal);
                        return dtVal;
                    case SimpleDataType.DecimalNumberType:
                        decimal dcVal;
                        decimal.TryParse(value, out dcVal);
                        return dcVal;
                    case SimpleDataType.IntNumberType:
                        double dblVal;
                        double.TryParse(value, out dblVal);
                        return (int)dblVal;
                    case SimpleDataType.TextType:
                        return value;
                    case SimpleDataType.YesNoType:
                        bool bVal;
                        bool.TryParse(value, out bVal);
                        return bVal;
                    case SimpleDataType.GuidType:
                        return new Guid(value);
                    case SimpleDataType.DoubleNumberType:
                        double dblVal2;
                        double.TryParse(value, out dblVal2);
                        return dblVal2;
                    case SimpleDataType.EnumType:
                        return int.Parse(value);
                    default:
                        return value;
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="simpleType"></param>
        /// <returns></returns>
        public static Type ToSystemType(SimpleDataType simpleType)
        {
            switch (simpleType)
            {
                case SimpleDataType.DateTimeType:
                    return typeof(DateTime);
                case SimpleDataType.DecimalNumberType:
                    return typeof(decimal);
                case SimpleDataType.IntNumberType:
                    return typeof(int);
                case SimpleDataType.TextType:
                    return typeof(string);
                case SimpleDataType.YesNoType:
                    return typeof(bool);
                case SimpleDataType.GuidType:
                    return typeof(Guid);
                case SimpleDataType.DoubleNumberType:
                    return typeof(double);
                case SimpleDataType.EnumType:
                    return typeof(int);
                case SimpleDataType.StringListType:
                    return typeof(List<string>);
                case SimpleDataType.IntListType:
                    return typeof(List<int>);
                default:
                    return typeof(string);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static SimpleDataType ToSimpleDataType(Type type)
        {
            if (type == typeof(DateTime))
                return SimpleDataType.DateTimeType;
            else if (type == typeof(decimal) || type == typeof(double) ||
                type == typeof(float))
                return SimpleDataType.DecimalNumberType;
            else if (type == typeof(int) || type == typeof(Int16) ||
                type == typeof(Int32) || type == typeof(Int64))
                return SimpleDataType.IntNumberType;
            else if (type == typeof(string))
                return SimpleDataType.TextType;
            else if (type == typeof(bool))
                return SimpleDataType.YesNoType;
            else if (type == typeof(Guid))
                return SimpleDataType.GuidType;
            else if (type == typeof(List<int>))
                return SimpleDataType.IntListType;
            else if (type == typeof(List<string>))
                return SimpleDataType.StringListType;
            else if (type == typeof(double))
                return SimpleDataType.DoubleNumberType;
            else if (type.IsEnum)
                return SimpleDataType.EnumType;
            else
                return SimpleDataType.ComplexType;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool IsSimpleDataType(Type type)
        {
            if (type == typeof(DateTime))
                return true;
            else if (type == typeof(decimal))
                return true;
            else if (type == typeof(int))
                return true;
            else if (type == typeof(string))
                return true;
            else if (type == typeof(bool))
                return true;
            else if (type == typeof(Guid))
                return true;
            else if (type == typeof(List<int>))
                return true;
            else if (type == typeof(List<string>))
                return true;
            else if (type == typeof(double))
                return true;
            else if (type.IsEnum)
                return true;
            else
                return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataType"></param>
        /// <param name="fieldValue"></param>
        /// <returns></returns>
        public static string ReadValueAsString(SimpleDataType dataType, object fieldValue)
        {
            object value = SimpleDataTypeUtil.ReadDbValue(dataType, fieldValue);
            if (value == null || value == SimpleDataTypeUtil.GetNullValue(SimpleDataType.TextType))
                return null;
            else
                return value.ToString();
        }
    }
}
